package cn.cool.types.design.framework.link.model2.chain;

import lombok.Data;

@Data
public class LinkedList<E> implements ILink<E> {
    /** 责任链名称 */
    private final String name;

    transient int size = 0;

    /** 哨兵头节点 */
    transient Node<E> head;
    /** 哨兵尾节点 */
    transient Node<E> tail;

    public LinkedList(String name) {
        this.name = name;
        // 初始化虚拟头节点和虚拟尾节点
        this.head = new Node<>(null);
        this.tail = new Node<>(null);
        this.head.next = this.tail;
        this.tail.prev = this.head;
    }

    @Override
    public boolean add(E e) {
        addLast(e);  // 修改：默认添加到尾部（更符合常规链表行为）
        return true;
    }

    @Override
    public boolean addFirst(E e) {
        addToHead(new Node<>(e));
        size++;  // 增加size计数
        return true;
    }

    @Override
    public boolean addLast(E e) {
        addToLast(new Node<>(e));
        size++;  // 增加size计数
        return true;
    }

    @Override
    public boolean remove(Object o) {
        if (o == null) {
            for (Node<E> x = head.next; x != tail; x = x.next) {
                if (x.item == null) {
                    removeNode(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = head.next; x != tail; x = x.next) {
                if (o.equals(x.item)) {
                    removeNode(x);
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public E get(int index) {
        checkElementIndex(index);  // 检查索引有效性
        return node(index).item;
    }

    @Override
    public void printLinkList() {
        if (size == 0) {
            System.out.println("链表为空");
        } else {
            System.out.print("目前的列表，头节点：" + head.next.item +
                    " 尾节点：" + tail.prev.item + " 整体：");
            for (Node<E> x = head.next; x != tail; x = x.next) {
                System.out.print(x.item + (x.next != tail ? "，" : ""));
            }
            System.out.println();
        }
    }

    // ===== 内部工具方法 =====
    private Node<E> node(int index) {
        // 优化遍历：根据位置决定从头还是从尾开始遍历
        if (index < (size >> 1)) {
            Node<E> x = head.next;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node<E> x = tail.prev;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }

    private void checkElementIndex(int index) {
        if (index < 0 || index >= size)
            throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);
    }

    private void addToHead(Node<E> node) {
        node.prev = head;
        node.next = head.next;
        head.next.prev = node;
        head.next = node;
    }

    private void addToLast(Node<E> node) {
        node.prev = tail.prev;
        node.next = tail;
        tail.prev.next = node;
        tail.prev = node;
    }

    private void removeNode(Node<E> node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;

        node.prev = null;  // 清理引用（帮助GC）
        node.next = null;
        node.item = null;
        size--;  // 减少size计数
    }

    protected static class Node<E> {
        E item;
        Node<E> prev;
        Node<E> next;

        public Node(E item) {
            this.item = item;
        }

        public Node(E item, Node<E> prev, Node<E> next) {
            this.item = item;
            this.prev = prev;
            this.next = next;
        }
    }
}